#pragma once
#include "sock.hpp"
#include <pthread.h>
#include <functional>
#include <unistd.h>

using func_t = std::function<void(int)>;

class ThreadDate
{
public:
    ThreadDate(int sock, func_t func)
    :_sockId(sock), _func(func)
    {}
public:
    int _sockId;
    func_t _func;
};

class HttpServer
{
public:
    HttpServer(uint16_t port, std::string ip = "0.0.0.0")
        : _port(port), _ip(ip)
    {
        // 服务器初始化
        _listen_sock = _sock.Socket();
        _sock.Bind(_listen_sock, port, ip);
        _sock.Listen(_listen_sock);
    }

    void BindService(func_t func)
    {
        _func = func;
    }

    void Start()
    {
        while(true)
        {
            int sockId = _sock.Accept(_listen_sock);

            // 创建线程执行任务
            pthread_t tid;
            ThreadDate* td = new ThreadDate(sockId, _func);
            pthread_create(&tid, nullptr, Service, td);
        }
    }

private:
    static void* Service(void* args)
    {
        pthread_detach(pthread_self()); // 线程剥离
        ThreadDate* td = (ThreadDate*)args;

        td->_func(td->_sockId);

        close(td->_sockId);

        delete td;

        return nullptr;
    }

private:
    uint16_t _port;
    std::string _ip;
    int _listen_sock;
    Sock _sock;
    func_t _func;
};